﻿using System.Collections.Generic;
using System.Diagnostics;

namespace MakeBorderless
{
    internal static class Styler
    {
        public static List<Process> GetVisibleWindowsAsProcess()
        {
            List<Process> procs = new List<Process>();
            foreach (Process p in Process.GetProcesses("."))
            {
                try
                {
                    if (!string.IsNullOrEmpty(p.MainWindowTitle) && WinAPI.IsWindowVisible(p.MainWindowHandle))
                    {
                        procs.Add(p);
                    }
                }
                catch { }
            }

            return procs;
        }

        private static List<Process> GetAllProcessWithWindowName(string name)
        {
            List<Process> procs = new List<Process>();
            foreach (Process p in Process.GetProcesses())
            {
                if (p.MainWindowTitle.ToLower() == name.ToLower())
                {
                    procs.Add(p);
                }
            }
            return procs;
        }

        public static void SetAllBorderless(string name, bool useWindow)
        {
            List<Process> procs;
            if (useWindow)
            {
                procs = GetAllProcessWithWindowName(name);
            }
            else
            {
                procs = new List<Process>(Process.GetProcessesByName(name));
            }
            foreach (Process p in procs)
            {
                SetBorderless(p);
            }
        }

        public static void ResetAllBorders(string name, bool useWindow)
        {
            List<Process> procs;
            if (useWindow)
            {
                procs = GetAllProcessWithWindowName(name);
            }
            else
            {
                procs = new List<Process>(Process.GetProcessesByName(name));
            }
            foreach (Process p in procs)
            {
                ResetBorder(p);
            }
        }

        public static void SetBorderless(Process proc)
        {
            int lStyle = WinAPI.GetWindowLong(proc.MainWindowHandle, WinAPI.GWL_STYLE);
            lStyle &= ~(WinAPI.WS_CAPTION | WinAPI.WS_THICKFRAME | WinAPI.WS_SYSMENU);
            WinAPI.SetWindowLong(proc.MainWindowHandle, WinAPI.GWL_STYLE, lStyle);

            int lExStyle = WinAPI.GetWindowLong(proc.MainWindowHandle, WinAPI.GWL_EXSTYLE);
            lExStyle &= ~(WinAPI.WS_EX_DLGMODALFRAME | WinAPI.WS_EX_CLIENTEDGE | WinAPI.WS_EX_STATICEDGE);
            WinAPI.SetWindowLong(proc.MainWindowHandle, WinAPI.GWL_EXSTYLE, lExStyle);

            UpdateWindow(proc);
        }

        public static void ResetBorder(Process proc)
        {
            int lStyle = WinAPI.GetWindowLong(proc.MainWindowHandle, WinAPI.GWL_STYLE);
            lStyle |= (WinAPI.WS_CAPTION | WinAPI.WS_THICKFRAME | WinAPI.WS_SYSMENU);
            WinAPI.SetWindowLong(proc.MainWindowHandle, WinAPI.GWL_STYLE, lStyle);

            int lExStyle = WinAPI.GetWindowLong(proc.MainWindowHandle, WinAPI.GWL_EXSTYLE);
            lExStyle |= (WinAPI.WS_EX_DLGMODALFRAME | WinAPI.WS_EX_CLIENTEDGE | WinAPI.WS_EX_STATICEDGE);
            WinAPI.SetWindowLong(proc.MainWindowHandle, WinAPI.GWL_EXSTYLE, lExStyle);

            UpdateWindow(proc);
        }

        public static void UpdateWindow(Process proc)
        {
            WinAPI.SetWindowPos(
                proc.MainWindowHandle,
                WinAPI.HWND_NOTOPMOST,
                0, 0, 0, 0,
                WinAPI.SetWindowPosFlags.IgnoreResize |
                WinAPI.SetWindowPosFlags.FrameChanged |
                WinAPI.SetWindowPosFlags.DrawFrame |
                WinAPI.SetWindowPosFlags.IgnoreMove);
        }

        public static bool IsStyled(Process proc)
        {
            int style = WinAPI.GetWindowLong(proc.MainWindowHandle, WinAPI.GWL_STYLE);
            int test = style | ~(WinAPI.WS_CAPTION | WinAPI.WS_SYSMENU | WinAPI.WS_THICKFRAME);
            return (test != -1);
        }
    }
}